package cn.edu.nuc.zyb.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import cn.edu.nuc.zyb.model.Cart;
import cn.edu.nuc.zyb.model.Goods;
import cn.edu.nuc.zyb.model.User;

/**
 * 这个类相当于服务器 与客户端进行交互
 * 
 * @author 张彦博
 *
 */
public class Server extends Thread {

	public ServerSocket socket;

	/**
	 * 这个方法是服务器的构造方法，在new时监听4000端口
	 */
	public Server() {
		try {
			socket = new ServerSocket(4000);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * send方法负责从服务器返回一个boolean值
	 * 
	 * @param os
	 *            输出流
	 * @param dos
	 *            数据输出流
	 */
	public void send(boolean flag, Socket socket) {
		OutputStream os = null;
		DataOutputStream dos = null;
		try {
			os = socket.getOutputStream();
			dos = new DataOutputStream(os);
			dos.writeBoolean(flag);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	/**
	 * 线程run()方法 服务器关键操作都在此方法当中
	 */
	@Override
	public void run() {
		while (true) {
			Socket s = null;
			InputStream is = null;
			DataInputStream dis = null;
			try {
				// 写在while(true) 来一个请求接受一个若无请求 则程序执行停止在此处
				s = socket.accept();
				is = s.getInputStream();
				dis = new DataInputStream(is);
				String msg = dis.readUTF();
				String m[] = msg.split(",");// 分割字符串
				// 用switch语句进行判断
				switch (m[0]) {
				// 服务器树立用户登陆校验
				case "login":
					FileOutputStream finput = new FileOutputStream("D:\\store\\personNum\\" + m[1]);
					ObjectOutputStream ooutput = new ObjectOutputStream(finput);
					ooutput.writeObject(1);
					ooutput.close();
					finput.close();

					File file = new File("D:\\store\\user");
					File[] files = file.listFiles();
					int sum = 0;
					FileInputStream fis = null;
					ObjectInputStream ois = null;
					for (int i = 0; i < files.length; i++) {
						fis = new FileInputStream(files[i]);
						ois = new ObjectInputStream(fis);
						User user = (User) ois.readObject();
						int password = Integer.valueOf(m[2]);

						if (m[1].equals(user.getUsername()) && password == user.getPassword()) {
							boolean flag = true;
							send(flag, s);
							System.out.println("登陆成功" + flag);
						} else {
							sum++;
						}
						fis.close();
						ois.close();
					}
					if (sum == files.length) {
						boolean flag = false;
						send(flag, s);
						System.out.println("登陆失败" + flag);
					}
					break;
				// 服务器处理用户注册
				case "regist":
					File file2 = new File("D:\\store\\user\\" + m[1]);
					if (file2.exists()) {
						boolean flag = false;
						send(flag, s);
						System.out.println("注册失败");
					} else {
						FileOutputStream fos = new FileOutputStream(file2);
						ObjectOutputStream oos = new ObjectOutputStream(fos);
						int password = Integer.valueOf(m[2]);
						int age = Integer.valueOf(m[4]);
						User user = new User(m[1], password, m[3], age);
						oos.writeObject(user);
						fos.close();
						oos.close();
						boolean flag = true;
						send(flag, s);
					}
					break;
				// 服务器处理管理员添加货物
				case "addgoods":
					File file3 = new File("D:\\store\\goods");
					File[] files3 = file3.listFiles();// 货物编号根据文件数目进行自增
					int gid = files3.length;
					float price = Float.valueOf(m[2]);
					int num = Integer.valueOf(m[3]);
					File exsit = new File("D:\\store\\goods\\" + m[1]);
					if (!exsit.exists()) {
						FileOutputStream fos = new FileOutputStream("D:\\store\\goods\\" + m[1]);
						ObjectOutputStream oos = new ObjectOutputStream(fos);
						Goods goods = new Goods(gid, m[1], price, num, m[4]);
						oos.writeObject(goods);
						fos.close();
						oos.close();
						boolean flag = true;
						System.out.println("添加成功");
						send(flag, s);
					} else {
						boolean flag = false;
						System.out.println("添加失败");
						send(flag, s);
					}
					break;
				// 服务器处理用户查询货物
				case "searchgoods":
					File file4 = new File("D:\\store\\goods");
					File[] files4 = file4.listFiles();
					List<Goods> list = new ArrayList<>(); // 定义集合将符合条件的数据从本地取出来添加到此集合当中
					System.out.println(m[1]);// 测试

					FileInputStream fis1 = null;
					ObjectInputStream ois1 = null;
					for (int i = 0; i < files4.length; i++) {
						fis1 = new FileInputStream(files4[i]);
						ois1 = new ObjectInputStream(fis1);
						Goods goods1 = (Goods) ois1.readObject();
						String goodsName = m[1];
						if (goodsName.equals(goods1.getGoodsName())) {
							list.add(goods1);
							System.out.println("添加");
						}
					}
					fis1.close();
					ois1.close();
					System.out.println(list.size());
					ObjectOutputStream oo = new ObjectOutputStream(s.getOutputStream());
					oo.writeObject(list);// 发送到客户端一个list
					break;
				// 服务器处理用户获取列表
				case "listgoods":
					File file5 = new File("D:\\store\\goods");
					File[] files5 = file5.listFiles();
					List<Goods> listgoods = new ArrayList<>();// 将数据存到集合当中去
					FileInputStream fis2 = null;
					ObjectInputStream ois2 = null;
					for (int i = 0; i < files5.length; i++) {
						fis2 = new FileInputStream(files5[i]);
						ois2 = new ObjectInputStream(fis2);
						Goods goods1 = (Goods) ois2.readObject();
						listgoods.add(goods1);
						fis2.close();
						ois2.close();
					}
					System.out.println(listgoods.size());// 测试
					ObjectOutputStream ooo = new ObjectOutputStream(s.getOutputStream());
					ooo.writeObject(listgoods);// 发送给客户端一个集合
					break;
				// 服务器处理管理员货物查询
				case "adminsearchgoods":
					File file6 = new File("D:\\store\\goods");
					File[] files6 = file6.listFiles();
					ObjectOutputStream oooo = new ObjectOutputStream(s.getOutputStream());
					List<Goods> adminlistGoods = new ArrayList<>();
					System.out.println(m[1]);
					FileInputStream fis3 = null;
					ObjectInputStream ois3 = null;

					for (int i = 0; i < files6.length; i++) {
						fis3 = new FileInputStream(files6[i]);
						ois3 = new ObjectInputStream(fis3);
						Goods goods1 = (Goods) ois3.readObject();
						int id = Integer.valueOf(m[1]);
						if (id == goods1.getGid()) {
							adminlistGoods.add(goods1);
							System.out.println("添加");
						}
						fis3.close();
						ois3.close();
					}

					System.out.println(adminlistGoods.size());// 测试
					oooo.writeObject(adminlistGoods);
					break;
				// 服务器处理管理员修改货物
				case "changegoods":
					File file7 = new File("D:\\store\\goods\\" + m[1]);
					if (file7.exists()) {
						FileInputStream fis4 = new FileInputStream("D:\\store\\goods\\" + m[1]);
						ObjectInputStream obi = new ObjectInputStream(fis4);
						Goods go = (Goods) obi.readObject();// 先从文件中读出来 反序列化出来
						fis4.close();
						obi.close();
						float prices = Float.valueOf(m[2]);
						int nums = Integer.valueOf(m[3]);

						FileOutputStream foss = new FileOutputStream("D:\\store\\goods\\" + m[1]);
						ObjectOutputStream ob = new ObjectOutputStream(foss);
						Goods gg = new Goods(go.getGid(), m[1], prices, nums, m[4]);
						ob.writeObject(gg);
						foss.close();
						ob.close();
						boolean flagg = true;
						send(flagg, s);
					} else {
						boolean flagg = false;
						send(flagg, s);
					}
					break;
				// 服务器管理员删除货物
				case "deletegoods":
					File file8 = new File("D:\\store\\goods\\" + m[1]);
					if (file8.exists()) {
						boolean flags = file8.delete();
						send(flags, s);// 从服务器端返回消息来确定是否删除成功
					} else {
						boolean flags = false;
						send(flags, s);
					}
					break;
				// 服务器处理用户查看商品
				case "lookgoods":
					FileInputStream fis6 = new FileInputStream("D:\\store\\goods\\" + m[1]);
					ObjectInputStream ois6 = new ObjectInputStream(fis6);
					Goods goods6 = (Goods) ois6.readObject();
					fis6.close();
					ois6.close();
					ObjectOutputStream oos6 = new ObjectOutputStream(s.getOutputStream());
					oos6.writeObject(goods6);
					break;
				case "addcart":
					File fie7 = new File("D:\\store\\cart\\" + m[5]);
					fie7.mkdir();// 创建一个目录名用户名的文件夹
					FileOutputStream fos7 = new FileOutputStream(fie7 + "\\" + m[2]);// m[2]商品名
					ObjectOutputStream oos7 = new ObjectOutputStream(fos7);
					int id = Integer.valueOf(m[1]);
					float pri = Float.valueOf(m[3]);
					int numbers = Integer.valueOf(m[4]);
					Cart cart = new Cart(id, m[2], pri, numbers);
					oos7.writeObject(cart);// 将添加之后的商品写入到目录名为 m[5]的文件夹下
					oos7.close();

					boolean f = true;
					send(f, s);
					break;
				// 服务器处理购物车列表显示
				case "listcart":
					File fil8 = new File("D:\\store\\cart\\" + m[1]);
					List<Cart> l = new ArrayList<>();
					File[] fils8 = fil8.listFiles();// 遍历[1]文件目录下的所有文件实现购物车显示
					FileInputStream fi8 = null;
					ObjectInputStream oi8 = null;
					try {
						// 若没有文件 会抛出空指针异常
						for (int i = 0; i < fils8.length; i++) {
							fi8 = new FileInputStream(fils8[i]);
							oi8 = new ObjectInputStream(fi8);
							Cart c = (Cart) oi8.readObject();
							l.add(c);
							fi8.close();
							oi8.close();
						}
					} catch (Exception e) {
						System.out.println("购物车里没有商品");
					}

					ObjectOutputStream oos8 = new ObjectOutputStream(s.getOutputStream());
					oos8.writeObject(l);// 若集合中没有内容 则发送回去一个空的集合
					break;
				case "settleaccounts":
					File file9 = new File("D:\\store\\money\\" + m[1]);
					file9.mkdir();// 创建目录名为[1]的文件夹
					// 将钱属性当成文件名序列化到[1]目录下
					FileOutputStream fos8 = new FileOutputStream(file9 + "\\" + m[2]);
					ObjectOutputStream ooss8 = new ObjectOutputStream(fos8);
					ooss8.writeObject(m[2]);

					// 同时会删除[1]目录下所有文件 包括自身
					File cleancart = new File("D:\\store\\cart\\" + m[1]);
					File[] carts = cleancart.listFiles();
					try {
						for (int i = 0; i < carts.length; i++) {
							if (carts[i].getName().endsWith("")) {
								carts[i].delete();
							}
						}
						cleancart.delete();
					} catch (Exception e) {
						System.out.println("哈哈 购物车里没东西");
					}
					boolean ff = true;
					send(ff, s);
					break;
				// 服务器处理改变库存 这里有些小问题
				case "changenum":
					File file10 = new File("D:\\store\\goods");
					File[] files10 = file10.listFiles();
					FileInputStream fis9 = null;// 服务器读取本地的goods文件
					ObjectInputStream ois9 = null;
					FileInputStream fi9 = null;// 服务器读取本地cart文件
					ObjectInputStream oi9 = null;
					FileOutputStream fos9 = null;// 服务器往本地goods文件中修改数量
					ObjectOutputStream oos9 = null;
					List<Goods> listgood = new ArrayList<>();
					for (int i = 0; i < files10.length; i++) {
						fis9 = new FileInputStream(files10[i]);
						ois9 = new ObjectInputStream(fis9);
						Goods goodsnum = (Goods) ois9.readObject();
						int oldnum = goodsnum.getNum();// 获取了原库存数目
						int cartnum = 0;
						File read = new File("D:\\store\\cart\\" + m[1] + "\\" + files10[i].getName());
						// 文件存在时 在删除
						if (read.exists()) {
							fi9 = new FileInputStream("D:\\store\\cart\\" + m[1] + "\\" + files10[i].getName());
							oi9 = new ObjectInputStream(fi9);
							Cart ca = (Cart) oi9.readObject();
							cartnum = ca.getNum();// 获取了购物车购买的数量
							oi9.close();
							fi9.close();
						}
						int nownum = oldnum - cartnum;

						Goods newGood = new Goods(goodsnum.getGid(), goodsnum.getGoodsName(), goodsnum.getPrice(),
								nownum, goodsnum.getIntro());// 将新的文件再重新序列化回去
						fos9 = new FileOutputStream(files10[i]);
						oos9 = new ObjectOutputStream(fos9);
						oos9.writeObject(newGood);
						oos9.close();
						fos9.close();

						listgood.add(newGood);
						ois9.close();
						fis9.close();
					}
					ObjectOutputStream outstream = new ObjectOutputStream(s.getOutputStream());
					outstream.writeObject(listgood);
					break;
				case "exitlogin":
					File fexit = new File("D:\\store\\personNum\\" + m[1]);
					fexit.delete();
					break;
				}

			} catch (Exception e) {
				System.out.println("连接失败");
			}
		}
	}

}
